// Fill out your copyright notice in the Description page of Project Settings.


#include "QuickAssetAction.h"

#include "AssetToolsModule.h"
#include "EditorAssetLibrary.h"
#include "EditorUtilityLibrary.h"
#include "ObjectTools.h"
#include "Materials/MaterialInstanceConstant.h"
#include "SuperManager/DebugHeader.h"
#include "Misc/MessageDialog.h"
#include "AssetRegistry/AssetRegistryModule.h"


void UQuickAssetAction::TestFunc()
{
	Print(TEXT("Working"),FColor::Cyan);
	PrintLog(TEXT("Working"));
}

void UQuickAssetAction::DuplicateAssets(int32 NumOfDuplicates)
{
	if (NumOfDuplicates <= 0 )
	{
		// Print(TEXT("Please enter a VALID number"),FColor::Red);
		
		ShowMsgDialog(EAppMsgType::Type::Ok,TEXT("Please enter a VALID number"));
	}

	TArray<FAssetData> SelectedAssetsData = UEditorUtilityLibrary::GetSelectedAssetData();
	uint32 Counter = 0;

	for(const FAssetData& SelectedAssetData : SelectedAssetsData)
	{
		for(int i = 0 ; i < NumOfDuplicates ; i++)
		{
			const FString SourceAssetPath = SelectedAssetData.ObjectPath.ToString();
			const FString NewDuplicatedAssetName = SelectedAssetData.AssetName.ToString() + TEXT("_") + FString::FromInt(i);
			const FString NewPathName = FPaths::Combine(SelectedAssetData.PackagePath.ToString(),NewDuplicatedAssetName);

			if(UEditorAssetLibrary::DuplicateAsset(SourceAssetPath,NewPathName))
			{
				UEditorAssetLibrary::SaveAsset(NewPathName,false);
				Counter++;
			}
		}
	}

	if (Counter > 0)
	{
		ShowNotifyInfo(TEXT("Successfully duplicated " + FString:: FromInt(Counter) + " files"));
	} 

}

void UQuickAssetAction::AddPrefixes()
{
	TArray<UObject*> SelectedObjects = UEditorUtilityLibrary::GetSelectedAssets();
	uint32 Counter = 0;

	for (UObject* SelectedObject : SelectedObjects)
	{
		if(!IsValid(SelectedObject)) continue;

		FString* PrefixFound = PrefixMap.Find(SelectedObject->GetClass());

		if(!PrefixFound || PrefixFound->IsEmpty())
		{
			Print(TEXT("Failed to find prefix for class ") + SelectedObject->GetClass()->GetName(),FColor::Red);
			continue;
		}

		FString OldName = SelectedObject->GetName();

		if(OldName.StartsWith(*PrefixFound))
		{
			Print(OldName + TEXT("already has prefix added"),FColor::Red);
			continue;
		}

		if(SelectedObject->IsA<UMaterialInstanceConstant>())
		{
			OldName.RemoveFromStart(TEXT("M_"));
			OldName.RemoveFromEnd(TEXT("_Inst"));
		}
		
		const FString NewNameWithPrefix = *PrefixFound + OldName;

		UEditorUtilityLibrary::RenameAsset(SelectedObject,NewNameWithPrefix);

		++Counter;

		ShowNotifyInfo(TEXT("Successfully renamed" + FString::FromInt(Counter) + "assets"));
	}
}

void UQuickAssetAction::RemoveUnusedAssets()
{
	FixUpRedirectors();
	
	TArray<FAssetData> SelectedAssetsData = UEditorUtilityLibrary::GetSelectedAssetData();
	TArray<FAssetData> UnusedAssetData;

	for (const FAssetData& SelectedAssetData : SelectedAssetsData)
	{
		TArray<FString> AssetRefrencers = UEditorAssetLibrary::FindPackageReferencersForAsset(SelectedAssetData.ObjectPath.ToString());

		if(AssetRefrencers.Num() == 0 )
		{
			UnusedAssetData.Add(SelectedAssetData);
		}
	}

	if (UnusedAssetData.Num() == 0)
	{
		ShowMsgDialog(EAppMsgType :: Ok, TEXT("No unused asset found among selected assets"),false);
		return;
	}

	const int32 NumOfAssetsDeleted = ObjectTools::DeleteAssets(UnusedAssetData);

	if(NumOfAssetsDeleted == 0) return;

	ShowNotifyInfo(TEXT("Successfully deleted" + FString::FromInt(NumOfAssetsDeleted) + "unused assets"));
}

void UQuickAssetAction::FixUpRedirectors()
{
	TArray<UObjectRedirector*> RedirectorsToFixArray;

	FAssetRegistryModule& AssetRegistryModule = FModuleManager::Get().LoadModuleChecked<FAssetRegistryModule>(TEXT("AssetRegistry"));

	FARFilter Filter;
	Filter.bRecursivePaths = true;
	Filter.PackagePaths.Emplace("/Game");
	Filter.ClassNames.Emplace("ObjectRedirector");

	TArray<FAssetData> OutRedirectors;
	
	AssetRegistryModule.Get().GetAssets(Filter,OutRedirectors);

	for (const FAssetData& RedirectorData : OutRedirectors)
	{
		UObjectRedirector* RedirectorToFix = Cast<UObjectRedirector>(RedirectorData.GetAsset());

		if(!IsValid(RedirectorToFix)) return;

		RedirectorsToFixArray.Add(RedirectorToFix);
	}


	FAssetToolsModule& AssetToolsModule = FModuleManager::Get().LoadModuleChecked<FAssetToolsModule>(TEXT("AssetTools"));
	AssetToolsModule.Get().FixupReferencers(RedirectorsToFixArray);
}
